/*
 * Copyright (C) 2011 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ros.android.android_tutorial_image_transport;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;

import org.ros.address.InetAddressFactory;
import org.ros.android.BitmapFromCompressedImage;
import org.ros.android.MessageCallable;
import org.ros.android.RosActivity;
import org.ros.android.view.RosImageView;
import org.ros.android.view.RosTextView;
import org.ros.android.view.ServoJoystickView;
import org.ros.android.view.VirtualJoystickView;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMainExecutor;

import java.util.Arrays;

import wheelview.WheelView;


/**
 * @author ethan.rublee@gmail.com (Ethan Rublee)
 * @author damonkohler@google.com (Damon Kohler)
 */
public class MainActivity extends RosActivity implements CompoundButton.OnCheckedChangeListener
{
  private static final int PROJECTOR_POWERON       = 1;
  private static final int PROJECTOR_POWEROFF      = 2;
  private static final int PROJECTOR_LIGHT_LEVEL_1 = 3;  //light level min
  private static final int PROJECTOR_DESK_TOP      = 9;
  private static final int PROJECTOR_DESK_DOWN     = 10;
  private static final int PROJECTOR_HANG_TOP      = 11;
  private static final int PROJECTOR_HANG_DOWN     = 12;

  private VirtualJoystickView mobileBase_Joystick;
  private ServoJoystickView headServo_Joystick;
    private LightControl myLightControl;
  private RosImageView<sensor_msgs.CompressedImage> image;
  private Button sendTTSBtn;
  private EditText myEditText;
    private RadioGroup mRadioGroup;
    private RadioButton deskTopRBtn;
    private RadioButton deskDownRBtn;
    private RadioButton hangTopRBtn;
    private RadioButton hangDownRBtn;
    private RosTextView<head_arduino_msgs.Analog> noiseTextView;
  private RosTextView<head_arduino_msgs.Analog> lightTextView;
  private RosTextView<head_arduino_msgs.Analog> smokeTextView;
  private RosTextView<ros_arduino_msgs.AnalogFloat> currentTextView;
  private RosTextView<std_msgs.String> batteryTextView;
  private RosTextView<head_arduino_msgs.IIC> tempTextView;
  private RosTextView<head_arduino_msgs.IIC> humiTextView;
  private RosTextView<head_arduino_msgs.IIC> altiTextView;
  private RosTextView<head_arduino_msgs.Analog> dustTextView;
  private RosTextView<android_app_communication.androidLogMsg> robotToAndroidLog;
  public TextToSpeaker myAndroidTTS;
  public ProjectorControl mProjector;
  public static Boolean sendTTSFlag = false;
  public static Boolean sendLightFlag = false;
  public static Boolean projectorCMDFlag = false;
  public static String sendText = "";
  public static int projectorCMD = 0;
  private static final String TAG = MainActivity.class.getSimpleName();
  private static final String[] LIGHT_ARRY = new String[]{"旋转彩虹", "加载红灯", "加载绿灯", "加载蓝灯",
          "白灯闪烁", "红灯闪烁", "绿灯闪烁", "蓝灯闪烁"};

    private static String[] light_level;

    private static final String cameraTopic = "/usb_cam_node/image_raw/compressed";

  public MainActivity() {
    super("ImageTransportTutorial", "ImageTransportTutorial");
  }

    public static byte lightIndex;
  private String robotAndroidAllLog = "";
  private static ScrollView mScrollView;
  private static Handler mHandler;
  private TabHost tabHost;
  private Switch mSwitch;

    @SuppressWarnings("unchecked")
  @Override
  public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);  //set full screen
        setContentView(R.layout.main);

        tabHost = (TabHost) findViewById(R.id.my_tabhost);
        tabHost.setup();
        LayoutInflater.from(this).inflate(R.layout.sensor_tab, tabHost.getTabContentView());
        LayoutInflater.from(this).inflate(R.layout.projector_tab, tabHost.getTabContentView());
        TabHost.TabSpec tab1 = tabHost.newTabSpec("tab1")
                .setIndicator(this.getResources().getString(R.string.sensor_str)) // 设置标题
                .setContent(R.id.tab1); //设置内容
        tabHost.addTab(tab1);

        TabHost.TabSpec tab2 = tabHost.newTabSpec("tab2")
                .setIndicator(this.getResources().getString(R.string.projector_str))
                .setContent(R.id.tab2);
        // 添加第二个标签页
        tabHost.addTab(tab2);
        TabWidget tabWidget = tabHost.getTabWidget();
        int count = tabWidget.getChildCount(); //TabHost中有一个getTabWidget()的方法
           for (int i = 0; i < count; i++) {
                View view = tabWidget.getChildTabViewAt(i);
                view.getLayoutParams().height = 80;
                final TextView tv = (TextView) view.findViewById(android.R.id.title);
                tv.setTextSize(14.0f);
                tv.setGravity(Gravity.CENTER);
                tv.setTextColor(this.getResources().getColorStateList(R.color.title_green));
           }

        WheelView wva = (WheelView) findViewById(R.id.wheel_view);
        wva.setItems(Arrays.asList(LIGHT_ARRY), 1); //init selected position is 1 初始选中位置为1
        wva.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(int selectedIndex, String item) {
                Log.w(TAG, "selectedIndex: " + selectedIndex + ", item: " + item);
                lightIndex = (byte) (selectedIndex + 11);
                sendLightFlag = true;
            }

        });

        sendTTSBtn = (Button) findViewById(R.id.sendBtn);
        myEditText = (EditText) findViewById(R.id.ttsEditText);
        mScrollView = (ScrollView) findViewById(R.id.myScrollView);
        image = (RosImageView<sensor_msgs.CompressedImage>) findViewById(R.id.image);
        image.setTopicName(cameraTopic);
        image.setMessageType(sensor_msgs.CompressedImage._TYPE);
        image.setMessageToBitmapCallable(new BitmapFromCompressedImage());

        mobileBase_Joystick = (VirtualJoystickView) findViewById(R.id.mobileBase_joystick);
        headServo_Joystick = (ServoJoystickView) findViewById(R.id.headServo_joystick);
        myLightControl = new LightControl();

        sendTTSBtn.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                sendText = myEditText.getText().toString();
                if (sendText.length() != 0) {
                    sendTTSFlag = true;
                } else {
                    sendTTSFlag = false;
                    Utility.showToast(getApplicationContext(), getApplicationContext().getString(R.string.warn_str));
                }
            }
        });
        setROSTextView();
        mHandler = new Handler();

        scrollToBottom();
        mSwitch = (Switch) findViewById(R.id.projector_switch); //get projector switch
        mSwitch.setOnCheckedChangeListener(this);

        light_level = getResources().getStringArray(R.array.light_level);
        setSpinnerListener(light_level, 3, true);

        mRadioGroup  = (RadioGroup)findViewById(R.id.radioGroup);
        deskTopRBtn  = (RadioButton)findViewById(R.id.desk_top);
        deskDownRBtn = (RadioButton)findViewById(R.id.desk_down);
        hangTopRBtn  = (RadioButton)findViewById(R.id.hang_top);
        hangDownRBtn = (RadioButton)findViewById(R.id.hang_down);
        mRadioGroup.setOnCheckedChangeListener(new RadioGroupListener());
    }

    private void setSpinnerListener(String[] curs, int select, boolean monitor) {
        Spinner spinner = (Spinner)findViewById(R.id.light_spinner);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner, curs);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setSelection(select, true);
        if(monitor)
        {
            spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
                    TextView tv = (TextView)view;
                    tv.setTextColor(getResources().getColor(R.color.little_blue));    //设置颜色
                    tv.setTextSize(12.0f);    //设置大小
                    tv.setGravity(android.view.Gravity.CENTER_HORIZONTAL);   //设置居中
                    projectorCMDFlag = true;
                    projectorCMD = position + PROJECTOR_LIGHT_LEVEL_1;
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent){}
            });
        }
    }

    class RadioGroupListener implements RadioGroup.OnCheckedChangeListener{
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId)
        {
            projectorCMDFlag = true;
            if (checkedId == deskTopRBtn.getId()){
                projectorCMD = PROJECTOR_DESK_TOP;
            }else if (checkedId == deskDownRBtn.getId()){
                projectorCMD = PROJECTOR_DESK_DOWN;
            }else if(checkedId == hangTopRBtn.getId())
            {
                projectorCMD = PROJECTOR_HANG_TOP;
            }else if(checkedId == hangDownRBtn.getId())
            {
                projectorCMD = PROJECTOR_HANG_DOWN;
            }
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
    {
        projectorCMDFlag = true;
        if (isChecked) {
            projectorCMD = PROJECTOR_POWERON;
        } else {
            projectorCMD = PROJECTOR_POWEROFF;
        }
    }

  @Override
  protected void init(NodeMainExecutor nodeMainExecutor)
  {
    myAndroidTTS = new TextToSpeaker();
    mProjector = new ProjectorControl();

    NodeConfiguration nodeConfiguration =
        NodeConfiguration.newPublic(InetAddressFactory.newNonLoopback().getHostAddress(),
            getMasterUri());
    nodeMainExecutor.execute(image, nodeConfiguration.setNodeName("android/video_view"));
    nodeMainExecutor.execute(mobileBase_Joystick, nodeConfiguration.setNodeName("mobileBase_joystick"));
    nodeMainExecutor.execute(headServo_Joystick,  nodeConfiguration.setNodeName("headServo_joystick"));
    nodeMainExecutor.execute(myAndroidTTS,  nodeConfiguration.setNodeName("myAndroidTTS"));
    nodeMainExecutor.execute(mProjector,  nodeConfiguration.setNodeName("ProjectorControl"));
    nodeMainExecutor.execute(noiseTextView, nodeConfiguration.setNodeName("subNoise"));
    nodeMainExecutor.execute(lightTextView, nodeConfiguration.setNodeName("subLight"));
    nodeMainExecutor.execute(smokeTextView, nodeConfiguration.setNodeName("subSmoke"));
    nodeMainExecutor.execute(currentTextView, nodeConfiguration.setNodeName("subCurrent"));
    nodeMainExecutor.execute(batteryTextView, nodeConfiguration.setNodeName("subBattery"));
    nodeMainExecutor.execute(tempTextView, nodeConfiguration.setNodeName("subTemp"));
    nodeMainExecutor.execute(humiTextView, nodeConfiguration.setNodeName("subHumi"));
    nodeMainExecutor.execute(altiTextView, nodeConfiguration.setNodeName("subAlti"));
    nodeMainExecutor.execute(dustTextView, nodeConfiguration.setNodeName("subDust"));
    nodeMainExecutor.execute(myLightControl, nodeConfiguration.setNodeName("myLightControl"));
    nodeMainExecutor.execute(robotToAndroidLog, nodeConfiguration.setNodeName("subRobotAndroidLog"));
  }

  private void setROSTextView()
  {
    noiseTextView = (RosTextView<head_arduino_msgs.Analog>) findViewById(R.id.noise_text);
    noiseTextView.setTopicName("/head_arduino/sensor/noise_sensor");
    noiseTextView.setMessageType(head_arduino_msgs.Analog._TYPE);
    noiseTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.Analog>() {
      @Override
      public String call(head_arduino_msgs.Analog message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    lightTextView = (RosTextView<head_arduino_msgs.Analog>) findViewById(R.id.light_text);
    lightTextView.setTopicName("/head_arduino/sensor/light_sensor");
    lightTextView.setMessageType(head_arduino_msgs.Analog._TYPE);
    lightTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.Analog>() {
      @Override
      public String call(head_arduino_msgs.Analog message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    smokeTextView = (RosTextView<head_arduino_msgs.Analog>) findViewById(R.id.smoke_text);
    smokeTextView.setTopicName("/head_arduino/sensor/smoke_sensor");
    smokeTextView.setMessageType(head_arduino_msgs.Analog._TYPE);
    smokeTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.Analog>() {
      @Override
      public String call(head_arduino_msgs.Analog message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    currentTextView = (RosTextView<ros_arduino_msgs.AnalogFloat>) findViewById(R.id.current_text);
    currentTextView.setTopicName("/mobilebase_arduino/sensor/motors_current");
    currentTextView.setMessageType(ros_arduino_msgs.AnalogFloat._TYPE);
    currentTextView.setMessageToStringCallable(new MessageCallable<String, ros_arduino_msgs.AnalogFloat>() {
      @Override
      public String call(ros_arduino_msgs.AnalogFloat message) {
        double retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
      batteryTextView = (RosTextView<std_msgs.String>) findViewById(R.id.battery_text);
      batteryTextView.setTopicName("/battery_percent_topic");
      batteryTextView.setMessageType(std_msgs.String._TYPE);
      batteryTextView.setMessageToStringCallable(new MessageCallable<String, std_msgs.String>() {
          @Override
          public String call(std_msgs.String message) {
              return message.getData();
          }
      });
    tempTextView = (RosTextView<head_arduino_msgs.IIC>) findViewById(R.id.temp_text);
    tempTextView.setTopicName("/head_arduino/sensor/temp_sensor");
    tempTextView.setMessageType(head_arduino_msgs.IIC._TYPE);
    tempTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.IIC>() {
      @Override
      public String call(head_arduino_msgs.IIC message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    humiTextView = (RosTextView<head_arduino_msgs.IIC>) findViewById(R.id.humidity_text);
    humiTextView.setTopicName("/head_arduino/sensor/humi_sensor");
    humiTextView.setMessageType(head_arduino_msgs.IIC._TYPE);
    humiTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.IIC>() {
      @Override
      public String call(head_arduino_msgs.IIC message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    altiTextView = (RosTextView<head_arduino_msgs.IIC>) findViewById(R.id.altitude_text);
    altiTextView.setTopicName("/head_arduino/sensor/alti_sensor");
    altiTextView.setMessageType(head_arduino_msgs.IIC._TYPE);
    altiTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.IIC>() {
      @Override
      public String call(head_arduino_msgs.IIC message) {
        double retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    dustTextView = (RosTextView<head_arduino_msgs.Analog>) findViewById(R.id.dust_text);
    dustTextView.setTopicName("/head_arduino/sensor/dust_sensor");
    dustTextView.setMessageType(head_arduino_msgs.Analog._TYPE);
    dustTextView.setMessageToStringCallable(new MessageCallable<String, head_arduino_msgs.Analog>() {
      @Override
      public String call(head_arduino_msgs.Analog message) {
        short retValue = message.getValue();
        return String.valueOf(retValue);
      }
    });
    robotToAndroidLog = (RosTextView<android_app_communication.androidLogMsg>) findViewById(R.id.run_status_text);
    robotToAndroidLog.setTopicName("/android_communication/robotToAppLog");
    robotToAndroidLog.setMessageType(android_app_communication.androidLogMsg._TYPE);
    robotToAndroidLog.setMessageToStringCallable(new MessageCallable<String, android_app_communication.androidLogMsg>() {
      @Override
      public String call(android_app_communication.androidLogMsg message) {
          String logMsg = message.getMessage();
          robotAndroidAllLog = robotAndroidAllLog + logMsg + "\n";
          return robotAndroidAllLog;
      }
    });
  }

    public static void scrollToBottom() {
        mHandler.post(new Runnable() {
            public void run() {
                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
                mHandler.postDelayed(this, 900);
            }
        });
    }
}
